import tkinter as tk
from tkinter import ttk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.dates import DateFormatter
import mplfinance as mpf
import pandas as pd
from trading.core.data_model import MarketData
from trading.core.config import Config

# 初始化matplotlib配置
Config.setup_matplotlib()


class CombinedChart:
    """行情图表组件：整合分时图和多周期K线图（固定单行布局）"""

    def __init__(self, parent_frame: ttk.Frame):
        self.frame = ttk.LabelFrame(parent_frame, text="行情图表")
        self.frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 初始化K线类型选择控件（固定单行不换行）
        self._setup_kline_controls()
        # 初始化图表显示区域
        self._setup_chart_area()

        # 数据缓存
        self.current_data = None  # 市场数据对象
        self.stock_code = None  # 股票代码
        self.pre_close = 0.0  # 昨收价

    def _setup_kline_controls(self):
        """创建K线类型选择控件（支持多种周期）"""
        control_frame = ttk.Frame(self.frame)
        control_frame.pack(fill=tk.X, padx=5, pady=5)

        # K线类型配置（包含分时和多种周期K线）
        kline_types = [
            ("分时", "tick"),
            ("5分钟", "5min"),
            ("15分钟", "15min"),
            ("30分钟", "30min"),
            ("60分钟", "60min"),
            ("日K", "day"),
            ("周K", "week"),
            ("月K", "month"),
            ("季K", "quarter"),
            ("半年K", "halfyear"),
            ("年K", "year")
        ]

        self.kline_type = tk.StringVar(value="tick")  # 默认显示分时图

        # 所有按钮在一行显示（不换行）
        for i, (text, mode) in enumerate(kline_types):
            ttk.Radiobutton(
                control_frame,
                text=text,
                variable=self.kline_type,
                value=mode,
                command=self._update_chart
            ).grid(row=0, column=i, padx=10, pady=2, sticky=tk.W)

    def _setup_chart_area(self):
        """创建matplotlib图表显示区域"""
        self.fig, self.ax = plt.subplots(figsize=(8, 5), dpi=100)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame)  # 绑定Tkinter
        self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)  # 布局图表控件

    def update_data(self, data: MarketData, stock_code: str):
        """更新图表数据并刷新显示"""
        self.current_data = data
        self.stock_code = stock_code
        self.pre_close = data.close  # 更新昨收价
        self._update_chart()  # 触发图表刷新

    def _update_chart(self):
        """根据选中的K线类型更新图表内容"""
        if not self.current_data or not self.stock_code:
            return  # 数据不足时不更新

        ktype = self.kline_type.get()
        self.ax.clear()  # 清除当前图表内容

        # 绘制分时图或K线图
        if ktype == "tick":
            self._draw_tick_chart()
        else:
            self._draw_kline_chart(ktype)

        plt.tight_layout()  # 自动调整布局
        self.canvas.draw()  # 刷新画布

    def _draw_tick_chart(self):
        """绘制分时图"""
        tick_data = self.current_data.tick_data
        if tick_data is None or tick_data.empty:
            self.ax.set_title("暂无分时数据")
            return

        # 处理时间格式为datetime
        tick_data['trade_time'] = pd.to_datetime(tick_data['trade_time'])

        # 确定价格线颜色（涨红跌绿）
        line_color = 'red' if tick_data['close'].iloc[-1] >= self.pre_close else 'green'

        # 绘制实时价格线
        self.ax.plot(
            tick_data['trade_time'],
            tick_data['close'],
            label='实时价格',
            linewidth=1.5,
            color=line_color
        )

        # 绘制昨收价参考线
        self.ax.axhline(
            y=self.pre_close,
            color='gray',
            linestyle='--',
            label='昨收价'
        )

        # 设置图表标题和坐标轴
        self.ax.set_title(f'{self.stock_code}  分时图')
        self.ax.set_ylabel('价格 (元)')
        self.ax.xaxis.set_major_formatter(DateFormatter('%H:%M'))  # 时间格式化为小时:分钟
        self.ax.grid(True, linestyle='--', alpha=0.7)  # 网格线
        self.ax.legend()  # 显示图例

    def _draw_kline_chart(self, ktype: str):
        """绘制指定周期的K线图"""
        kline_data = self.current_data.kline_data.get(ktype)
        if kline_data is None or kline_data.empty:
            self.ax.set_title(f"暂无{ktype}K线数据")
            return

        # 周期名称映射（用于标题显示）
        period_map = {
            'day': '日',
            'week': '周',
            'month': '月',
            'quarter': '季',
            'halfyear': '半年',
            'year': '年'
        }
        period_suffix = period_map.get(ktype, ktype)

        # 使用mplfinance绘制蜡烛图
        mpf.plot(
            kline_data,
            type='candle',  # 蜡烛图类型
            style='charles',  # 图表样式
            title=f'{self.stock_code}  {period_suffix}K线',  # 标题
            ylabel='价格 (元)',  # Y轴标签
            ax=self.ax,  # 绑定到当前坐标轴
            volume=False,  # 不显示成交量
            show_nontrading=False  # 不显示非交易日
        )

        # 添加网格线
        self.ax.grid(True, linestyle='--', alpha=0.7)